package com.dudu.service.impl;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.util.JSONUtils;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.dudu.bean.ChargingRuleBean;
import com.dudu.bean.IvrDailRequestBean;
import com.dudu.bean.PoolAbilityInfoBean;
import com.dudu.dao.IvrDao;
import com.dudu.dao.MeetInfoDao;
import com.dudu.dao.SendNoticeDao;
import com.dudu.dao.UploadFileDao;
import com.dudu.enumeration.AbilityTypeEnum;
import com.dudu.model.UploadFileModel;
import com.dudu.service.IIvrNoticesService;
import com.dudu.service.IRuleService;
import com.dudu.timer.SendVoiceUtil;
import com.dudu.utils.PhoneUtils;

import core.CoreDao;
import core.CoreDaoInvoke;

/**
 * IVR外呼Service
 * 
 * @author gaoxs
 * 
 */
public class IvrNoticesServcieImpl implements IIvrNoticesService {
    private static final Logger log = core.util.Logger.getLogger(IvrNoticesServcieImpl.class.getSimpleName());
    // 用于查询数据用
    private CoreDao coreDao = CoreDaoInvoke.getInstance();
    // 语音信息
    private SendNoticeDao mSendNoticeDao = new SendNoticeDao();
    private UploadFileDao uploadfileDao = new UploadFileDao();
    private IvrDao ivrDao = new IvrDao();
    private MeetInfoDao meetDao = new MeetInfoDao();

    /**
     * 验证参数
     * 
     * @param ivrRequestBean
     * @return
     */
    public JSONObject checkIvrDial(IvrDailRequestBean ivrRequestBean) {
	JSONObject object = new JSONObject();
	for (int i = 0; i < ivrRequestBean.getCalled_data().size(); i++) {
	    JSONObject calledObj = ivrRequestBean.getCalled_data().getJSONObject(i);
	    String msg_id = calledObj.optString("msg_id");
	    if (msg_id.length() > 50) {
		object.put("result", "-1");
		object.put("describe", "参数值超长:" + "msg_id" + "超长，不能超过50");
		object.put("code", "0009");
		return object;
	    }

	    String called = calledObj.optString("called");
	    if (called.length() > 20) {
		object.put("result", "-1");
		object.put("describe", "参数值超长:" + "called" + "超长，不能超过20");
		object.put("code", "0009");
		return object;
	    }
	    if (StringUtils.isBlank(called)) {
		object.put("result", "-1");
		object.put("describe", "参数值为空:" + "called" + "不能为空");
		object.put("code", "0015");
		return object;
	    }
	    if (ivrRequestBean.getCheckcalled().equals("0")) {
		if (!PhoneUtils.isMobileOrPhone(called)) {
		    object.put("result", "-1");
		    object.put("describe", "号码格式错误号码:" + called);
		    object.put("code", "0004");
		    return object;
		}
	    }

	    String tts_content = ivrRequestBean.getTts_content();
	    int count = 0;
	    if (StringUtils.isNotBlank(tts_content)) {
		count = tts_content.split("\\{").length;
	    } else {
		for (int m = 1; m < 5; m++) {
		    String desp = calledObj.optString("para" + m);
		    if (StringUtils.isNotBlank(desp)) {
			object.put("result", "-1");
			object.put("describe", "前导音与参数不匹配，请修改");
			object.put("code", "0518");
			return object;
		    }
		}
	    }

	    for (int m = 1; m < count; m++) {
		String resp = "{" + m + "}";
		if (tts_content.indexOf(resp) == -1) {
		    object.put("result", "-1");
		    object.put("describe", "前导音占位符格式不对");
		    object.put("code", "0517");
		    return object;
		}
		String desp = calledObj.optString("para" + m);
		if (desp.length() > 50) {
		    object.put("result", "-1");
		    object.put("describe", "参数值超长:" + "para" + m + "超长，不能超过50");
		    object.put("code", "0009");
		    return object;
		}
		tts_content = tts_content.replace(resp, desp);
		if (tts_content.length() > 200) {
		    object.put("result", "-1");
		    object.put("describe", "参数值超长:" + "tts_content" + "超长，不能超过200");
		    object.put("code", "0009");
		    return object;
		}
	    }
	}
	if (ivrRequestBean.getContent_data() != null) {
	    if (ivrRequestBean.getContent_data().size() > 1) {
		object.put("result", "-1");
		object.put("describe", "暂不支持多任务");
		object.put("code", "0518");
		return object;
	    }
	    for (int i = 0; i < ivrRequestBean.getContent_data().size(); i++) {
		JSONObject one = ivrRequestBean.getContent_data().getJSONObject(i);
		if (one.getJSONArray("media_data").size() > 1) {
		    object.put("result", "-1");
		    object.put("describe", "暂不支持多任务");
		    object.put("code", "0518");
		    return object;
		}
		JSONArray media_data = one.getJSONArray("media_data");
		for (int m = 0; m < media_data.size(); m++) {
		    JSONObject mediaJSON = media_data.getJSONObject(m);
		    if (!mediaJSON.optString("media_type").equals("media")) {
			object.put("result", "-1");
			object.put("describe", "暂时只支持语音文件");
			object.put("code", "0518");
			return object;
		    }
		    UploadFileModel fileModel = uploadfileDao.queryFileInfoBymediaName(coreDao, mediaJSON.optString("media_content"));
		    if (null == fileModel) {
			object.put("result", "-1");
			object.put("describe", "语音文件名称未找到,请重新上传");
			object.put("code", "0510");
			return object;
		    }
		}
	    }
	}
	object.put("result", "0");
	return object;
    }

    /**
     * IVR 语音调研基础接口
     * 
     * @param ivrRequestBean
     * @param type
     *            type=0 基础业务,type=1 组合业务,type=2 多任务业务
     * @return
     */
    public JSONObject IvrDialNotice(IvrDailRequestBean ivrRequestBean, String type) {
	log.info("IvrNoticesServcieImpl.IvrDialNotice 发起IVR外呼");
	// 最终返回结果
	JSONObject object = new JSONObject();

	// 查询当前账号默认使用的多方通话能力通道
	// 获取语音短信能力类型标识
	String abilityType = AbilityTypeEnum.IVVR.getKey();
	// 能力配置查询
	IRuleService ruleService = new RuleServiceImpl();
	ChargingRuleBean chargingRule = ruleService.queryChargingRule(ivrRequestBean.getApp_key(), ivrRequestBean.getCust_account(), abilityType);
	// 判断查询的默认通道调用数据是否为空
	if (chargingRule != null) {
	    // 判断如果传入的时间为空，则默认使用当前时间+3分钟
	    if (chargingRule.getType().contains("YonYou")) { // 自建通道设置为空发，SendVoiceUtil.java类统一处理发送时间
		if (StringUtils.isBlank(ivrRequestBean.getSchedule_send_time()) || ivrRequestBean.getSchedule_send_time().equals("null")) {
		    ivrRequestBean.setSchedule_send_time("");
		}
	    } else {
		if (StringUtils.isBlank(ivrRequestBean.getSchedule_send_time()) || ivrRequestBean.getSchedule_send_time().equals("null")) {
		    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		    Date now = new Date();
		    Date nowAdd = new Date(now.getTime() + 3 * 60 * 1000);
		    ivrRequestBean.setSchedule_send_time(format.format(nowAdd));
		}
	    }

	    String displayNum = null;// 显号
	    String number_vest = null;// 地区
	    SendVoiceUtil sendUtil = new SendVoiceUtil();
	    PoolAbilityInfoBean poolAbilityInfo = sendUtil.queryPoolAbilityInfo(coreDao, ivrRequestBean.getApp_key(), ivrRequestBean.getCust_account(), chargingRule.getType(),
		    ivrRequestBean.getPool_ability_id(), displayNum, ivrRequestBean.getUsePlatNbr(), number_vest);
	    if (poolAbilityInfo == null) {
		if (AbilityTypeEnum.IVR_RONGL.getKey().equals(chargingRule.getType())) {
		    poolAbilityInfo = new PoolAbilityInfoBean();
		} else {
		    object.put("result", "-1");
		    object.put("errorMsg", "未配置对应显号;ability_type:" + chargingRule.getType());
		    object.put("describe", "未配置显号");
		    object.put("code", "0018");
		    return object;
		}
	    }
	    if (AbilityTypeEnum.IVR_YONYOU.getKey().equals(chargingRule.getType())) {
		if (type.equals("0")) {
		    object = this.sendIvrDial(AbilityTypeEnum.IVR_YONYOU.getKey(), poolAbilityInfo, ivrRequestBean);
		} else if (type.equals("1")) {
		    object = this.sendIvrDialcb(AbilityTypeEnum.IVR_YONYOU.getKey(), poolAbilityInfo, ivrRequestBean);
		} else if (type.equals("2")) {
		    object = this.sendMultipleIvrDial(AbilityTypeEnum.IVR_YONYOU.getKey(), poolAbilityInfo, ivrRequestBean);
		}

	    } else if (AbilityTypeEnum.IVR_RONGL.getKey().equals(chargingRule.getType())) {
		// 容联批量外呼,按钮自定义,一次批量发多个号
		if (type.equals("0")) {
		    object = this.sendIvrDial(AbilityTypeEnum.IVR_RONGL.getKey(), poolAbilityInfo, ivrRequestBean);
		} else if (type.equals("1")) {
		    object = this.sendIvrDialcb(AbilityTypeEnum.IVR_RONGL.getKey(), poolAbilityInfo, ivrRequestBean);
		} else if (type.equals("2")) {
		    object = this.sendMultipleIvrDial(AbilityTypeEnum.IVR_RONGL.getKey(), poolAbilityInfo, ivrRequestBean);
		}

	    } else {
		object.put("result", "-1");
		object.put("describe", "未配置线路");
		object.put("errorMsg", "未配置默认IVR外呼通道！voice_type:" + chargingRule.getType());
		object.put("code", "0010");
	    }
	} else {
	    // 未配置通道
	    object.put("result", "-1");
	    object.put("errorMsg", "未找到相应的能力配置！");
	    object.put("describe", "能力配置错误");
	    object.put("code", "0013");
	}

	return object;
    }

    /**
     * IVR 多任务语音调研
     * 
     * @param voice_type
     * @param poolAbilityInfo
     * @param ivrRequestBean
     * @return
     */
    private JSONObject sendMultipleIvrDial(String voice_type, PoolAbilityInfoBean poolAbilityInfo, IvrDailRequestBean ivrRequestBean) {
	JSONObject object = new JSONObject();
	object = saveMedia(ivrRequestBean.getContent_data(), voice_type);
	if (object.optString("result").equals("-1")) {
	    return object;
	}
	/**
	 * 后期优化为单独存表
	 */
	String mediaName = object.optString("media_name");
	object.remove("media_name");
	UploadFileModel fileModel = uploadfileDao.queryFileInfoBymediaName(coreDao, mediaName);
	JSONArray data = new JSONArray();
	for (int i = 0; i < ivrRequestBean.getCalled_data().size(); i++) {

	    JSONObject one = new JSONObject();
	    JSONObject calledObj = ivrRequestBean.getCalled_data().getJSONObject(i);
	    String msg_id = calledObj.optString("msg_id");
	    one.put("msg_id", msg_id);
	    String called = calledObj.optString("called");
	    one.put("called", called);

	    String tts_content = ivrRequestBean.getTts_content();
	    int count = tts_content.split("\\{").length;
	    for (int m = 1; m < count; m++) {
		String resp = "{" + m + "}";
		String desp = calledObj.optString("para" + m);
		tts_content = tts_content.replace(resp, desp);
	    }
	    String endDate = "";
	    String content = "";
	    String push_url = "";
	    String status = "-1";
	    JSONObject voiceId = null;
	    if (tts_content.length() <= 200) {
		String duduSessionID = UUID.randomUUID().toString();
		voiceId = SendVoiceUtil.saveNotice(duduSessionID, called, msg_id, voice_type, ivrRequestBean.getApp_key(), ivrRequestBean.getCaller(),
			poolAbilityInfo.getCharge_number(), poolAbilityInfo.getCharge_key(), ivrRequestBean.getCust_account(), ivrRequestBean.getPeriphery_code(),
			ivrRequestBean.getUserIdentify(), ivrRequestBean.getSchedule_send_time(), endDate, content, fileModel.getVoice_name(), push_url, tts_content,
			poolAbilityInfo.getDisplay_number(), ivrRequestBean.getBatch_number(), status, fileModel.getFileAddress(), fileModel.getMediaName(), coreDao);
	    }
	    if (voiceId == null) {
		one.put("state", "1");
		one.put("session_id", "");
	    } else {
		one.put("session_id", voiceId.optString("session_id"));
		one.put("state", "0");
	    }
	    data.add(one);
	}
	object.put("result", "0");
	object.put("describe", "语音短信存储成功");
	object.put("code", "0000");
	object.put("data", data);
	return object;
    }

    /**
     * 存数据
     * 
     * @param content_data
     * @param voice_type
     * @return
     */
    private JSONObject saveMedia(JSONArray content_data, String voice_type) {
	JSONObject object = new JSONObject();
	for (int i = 0; i < content_data.size(); i++) {
	    JSONObject one = content_data.getJSONObject(i);
	    JSONArray media_data = one.getJSONArray("media_data");
	    for (int m = 0; m < media_data.size(); m++) {
		JSONObject mediaJSON = media_data.getJSONObject(m);
		if (mediaJSON.optString("media_type").equals("media")) {
		    String mediaName = mediaJSON.optString("media_content");
		    UploadFileModel fileModel = uploadfileDao.queryFileInfoBymediaName(coreDao, mediaName);
		    if (null == fileModel) {
			object.put("result", "-1");
			object.put("describe", "语音文件名称未找到,请重新上传");
			object.put("code", "0510");
			return object;
		    } else {
			// 向通道上传文件
			JSONObject obj = SendVoiceUtil.uploadFile(coreDao, fileModel, mediaName, voice_type);
			if (obj.optString("result").equals("-1")) {
			    return obj;
			}
			object.put("media_name", mediaName);
		    }

		}
	    }
	}
	object.put("result", "0");
	return object;
    }

    /**
     * IVR语音调研组合业务
     * 
     * @param voice_type
     * @param poolAbilityInfo
     * @param ivrRequestBean
     * @return
     */
    private JSONObject sendIvrDialcb(String voice_type, PoolAbilityInfoBean poolAbilityInfo, IvrDailRequestBean ivrRequestBean) {
	JSONObject object = new JSONObject();
	UploadFileModel fileModel = new UploadFileModel();
	if (StringUtils.isNotBlank(ivrRequestBean.getMediaName())) {
	    fileModel = uploadfileDao.queryFileInfoBymediaName(coreDao, ivrRequestBean.getMediaName());
	    if (null == fileModel) {
		object.put("result", "-1");
		object.put("describe", "语音文件名称未找到,请重新上传");
		object.put("code", "0510");
		return object;
	    }
	    // 向通道上传文件
	    JSONObject obj = SendVoiceUtil.uploadFile(coreDao, fileModel, ivrRequestBean.getMediaName(), voice_type);
	    if (obj.optString("result").equals("-1")) {
		return obj;
	    }
	}
	JSONArray data = new JSONArray();
	for (int i = 0; i < ivrRequestBean.getCalled_data().size(); i++) {
	    JSONObject one = new JSONObject();
	    JSONObject calledObj = ivrRequestBean.getCalled_data().getJSONObject(i);
	    String msg_id = calledObj.optString("msg_id");
	    one.put("msg_id", msg_id);
	    String called = calledObj.optString("called");
	    one.put("called", called);
	    String tts_content = ivrRequestBean.getTts_content();
	    int count = tts_content.split("\\{").length;
	    for (int m = 1; m < count; m++) {
		String resp = "{" + m + "}";
		String desp = calledObj.optString("para" + m);
		tts_content = tts_content.replace(resp, desp);
	    }
	    String endDate = "";
	    String content = ivrRequestBean.getDigit_content();
	    String push_url = "";
	    String status = "-1";
	    JSONObject voiceId = null;
	    if (tts_content.length() <= 200) {
		String duduSessionID = UUID.randomUUID().toString();
		voiceId = SendVoiceUtil.saveNotice(duduSessionID, called, msg_id, voice_type, ivrRequestBean.getApp_key(), ivrRequestBean.getCaller(),
			poolAbilityInfo.getCharge_number(), poolAbilityInfo.getCharge_key(), ivrRequestBean.getCust_account(), ivrRequestBean.getPeriphery_code(),
			ivrRequestBean.getUserIdentify(), ivrRequestBean.getSchedule_send_time(), endDate, content, fileModel.getVoice_name(), push_url, tts_content,
			poolAbilityInfo.getDisplay_number(), ivrRequestBean.getBatch_number(), status, fileModel.getFileAddress(), fileModel.getMediaName(), coreDao);
	    }
	    if (voiceId == null) {
		one.put("state", "1");
		one.put("session_id", "");
	    } else {
		int meetId = meetDao.insertMeetBusiness(coreDao, ivrRequestBean.getCust_account(), voiceId.optString("session_id"), ivrRequestBean.getSms_signature(),
			ivrRequestBean.getCallback_interface_type(), ivrRequestBean.getDigit());
		if (meetId > -1) {
		    one.put("session_id", voiceId.optString("session_id"));
		    one.put("state", "0");
		} else {
		    one.put("state", "1");
		    one.put("session_id", "");
		}
	    }
	    data.add(one);
	}
	object.put("result", "0");
	object.put("describe", "语音短信存储成功");
	object.put("code", "0000");
	object.put("data", data);
	return object;
    }

    /**
     * IVR 语音调研
     * 
     * @param voice_type
     * @param poolAbilityInfo
     * @param ivrRequestBean
     * @return
     */
    private JSONObject sendIvrDial(String voice_type, PoolAbilityInfoBean poolAbilityInfo, IvrDailRequestBean ivrRequestBean) {
	// 最终返回结果
	UploadFileModel fileModel = new UploadFileModel();
	JSONObject object = new JSONObject();
	if (StringUtils.isNotBlank(ivrRequestBean.getMediaName())) {
	    fileModel = uploadfileDao.queryFileInfoBymediaName(coreDao, ivrRequestBean.getMediaName());
	    if (null == fileModel) {
		object.put("result", "-1");
		object.put("describe", "语音文件名称未找到,请重新上传");
		object.put("code", "0510");
		return object;
	    }
	    // 向通道上传文件
	    JSONObject obj = SendVoiceUtil.uploadFile(coreDao, fileModel, ivrRequestBean.getMediaName(), voice_type);
	    if (obj.optString("result").equals("-1")) {
		return obj;
	    }
	    ivrRequestBean.setContent("");
	} else if (StringUtils.isNotBlank(ivrRequestBean.getContent())) {
	    // 处理上传的文字信息
	    ivrRequestBean.setContent(ivrRequestBean.getContent().replaceAll("\\pP|\\pS", " "));
	    // 处理上传的文字的空格信息
	    ivrRequestBean.setContent(ivrRequestBean.getContent().replaceAll(" ", ","));
	    // 处理换行\tab\
	    ivrRequestBean.setContent(ivrRequestBean.getContent().replaceAll("\r|\n|\t", ""));
	    ivrRequestBean.setMediaName("");
	} else {
	    object.put("result", "-1");
	    object.put("describe", "文本内容和语音文件名称不能同时为空");
	    object.put("code", "0515");
	    return object;
	}
	JSONObject voiceAndSessionIds = SendVoiceUtil.saveNotices(ivrRequestBean.getCalled(), voice_type, ivrRequestBean.getApp_key(), ivrRequestBean.getCaller(),
		poolAbilityInfo.getCharge_number(), poolAbilityInfo.getCharge_key(), ivrRequestBean.getCust_account(), ivrRequestBean.getPeriphery_code(),
		ivrRequestBean.getUserIdentify(), ivrRequestBean.getSchedule_send_time(), ivrRequestBean.getEndDate(), ivrRequestBean.getContent(), fileModel.getVoice_name(),
		ivrRequestBean.getPush_url(), "", poolAbilityInfo.getDisplay_number(), ivrRequestBean.getBatch_number(), "-1", fileModel.getFileAddress(),
		fileModel.getMediaName(), coreDao, null);

	/**
	 * qinfx 2017-05-22 新增返回session_id
	 */
	JSONObject voice_ids = voiceAndSessionIds.getJSONObject("voiceIds");
	JSONObject session_ids = voiceAndSessionIds.getJSONObject("sessionIds");
	object.put("voice_id", voice_ids.toString());
	object.put("session_id", session_ids.toString());

	object.put("result", "0");
	object.put("describe", "语音短信存储成功");
	object.put("code", "0000");
	return object;
    }

    /**
     * 查询条数（分页用）
     * 
     * @param paramSql
     * @return
     */
    public Integer getTotal(String paramSql) {
	return ivrDao.getTotal(coreDao, paramSql);
    }

    /**
     * 查询数据（分页）
     * 
     * @param paramSql
     * @param pageSql
     * @return
     */
    public List<JSONObject> queryAll(String paramSql, String pageSql) {
	List<JSONObject> list = ivrDao.queryAll(coreDao, paramSql, pageSql);
	if (null == list) {
	    return list;
	}
	return list;
    }
}